package com.apes.fn.ssm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.ssm.model.BrandPriority;
import com.apes.fn.ssm.model.FittingMessage;
import com.apes.fn.ssm.repository.BrandPriorityDao;
import com.apes.fn.ssm.repository.BrandPriorityRepository;
import com.apes.fn.ssm.repository.FittingMessageRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.product.model.Brand;
import com.apes.scm.masterdata.product.repository.BrandRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.repository.LocationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 *
 *@Description : 测算品牌优先级配置
 * @Author : WSl
 */
@Service("brandPriorityService")
public class BrandPriorityService extends DomainService {

    @Autowired
    private BrandPriorityRepository brandPriorityRepository;

    @Autowired
    private FittingMessageRepository fittingMessageRepository;

    @Autowired
    private LocationRepository locationRepository;

    @Autowired
    private BrandRepository brandRepository;

    @Autowired
    private EnumerationRepository enumerationRepository;

    /**
     * 批量更新测算品牌优先级
     *
     */
    public Map batchUpdateBrandPriority(SimpleRequest request){
        //新增和修改
        List<BrandPriority> brandPriorityList = request.getA("brandPriorityItems", BrandPriority.class);
        Set<String> brandPrioritySet = new HashSet<>();

        //禁止添加重复数据
        brandPriorityList.forEach( brandPriority -> {
            String sole =  brandPriority.getLocation().getId() + brandPriority.getFittingName().getId() + brandPriority.getBrand().getId();
            if (!brandPrioritySet.add(sole)) throw new RuntimeException("请勿添加重复数据，请检查添加数据是否正确！");
        });

        //获取删除的数据,如果没有不删除
        if (Objects.nonNull(request.getJO().get("del"))){
            List<BrandPriority> delBrandPriorities = request.getA("del", BrandPriority.class);
            delBrandPriorities.forEach(brandPriority -> {
                String sole = brandPriority.getLocation().getId() + brandPriority.getFittingName().getId() + brandPriority.getBrand().getId();
                if (Objects.nonNull(brandPriority.getId()) && brandPrioritySet.add(sole)){
                    brandPriorityRepository.delete(brandPriority);
                }
            });
        }

        //保存并返回
        List<BrandPriority> resultBrandPriorities =
        brandPriorityList.stream().map( brandPriority -> brandPriorityRepository.saveAndFlush(brandPriority))
                .collect(Collectors.toList());
        Map brandPriorityItems = MapUtil.mapper("brandPriorityItems", resultBrandPriorities);
        return brandPriorityItems;

    }


    /**
     * 定制导入品牌优先级配置
     *
     */
    public JSONObject importBrandPriority (SimpleRequest request){
        //Excel信息
        JSONObject importData = request.get("importData");
        JSONArray titleColumnArray = new JSONArray();
        String key = appendImportReturn_New(importData, titleColumnArray);
        JSONObject returnData = new JSONObject();
        returnData.put(key, titleColumnArray);
        return returnData;
    }

    /**
     * 并行流导入
     * @param importData
     * @param titleColumnArray
     * @return
     */
    private String appendImportReturn_New(JSONObject importData, JSONArray titleColumnArray) {
        List distinct = Collections.synchronizedList(new ArrayList());
        Map<String, Map<String, Object>> cacheLocation = new ConcurrentHashMap<>();
        Map<String, Map<String, Object>> cacheBrand = new ConcurrentHashMap<>();
        Map<String, Map<String, Object>> cacheFittingMessage = new ConcurrentHashMap<>();
        Map<String, Map<String, Object>> cachePriority = new ConcurrentHashMap<>();
        AtomicReference<String> key = new AtomicReference<>();
        Set<String> locationAndFittingMessage = new HashSet<>();

        JSONArray titleArray = new JSONArray(8);
        titleArray.add("序号");
        titleArray.add("编号");
        titleArray.add("仓库");
        titleArray.add("仓库名称");
        titleArray.add("组合配件名称");
        titleArray.add("品牌");
        titleArray.add("优先级");
        titleArray.add("状态");
        titleArray.add("版本号");
        titleArray.add("有效");
        titleColumnArray.add(titleArray);

        List dataList = Collections.synchronizedList(new ArrayList());
        importData.forEach((k, v) -> {
            key.set(k);
            JSONArray importDataValueArray = (JSONArray) v;
            importDataValueArray.parallelStream().forEach( item -> {
                JSONArray iValueArray = (JSONArray) item;
                if (iValueArray.size() == 0) return;

                String locationId = iValueArray.get(0).toString();
                String fittingMessageName = iValueArray.get(2).toString();
                String brandId = iValueArray.get(3).toString();
                String priority = iValueArray.get(4).toString();
                switch (priority){
                    case "1" : priority = "001990";break;
                    case "2" : priority = "001989";break;
                    case "3" : priority = "001991";break;
                    case "4" : priority = "001992";break;
                }

                Boolean valid = iValueArray.get(5).toString().equals("是");
                JSONArray newDataArray = new JSONArray(13);
                if (Pattern.matches("[\\u4e00-\\u9fa5]*", locationId)) {    // 匹配中文
                    return;
                }
                Map<String, Object> location = this.cacheLocation_new(locationId, cacheLocation);
                Map<String, Object> fittingMessage = this.cacheFittingMessage_new(fittingMessageName, cacheFittingMessage);
                Map<String, Object> brand = this.cacheBrand_new(brandId, cacheBrand);
                Map<String, Object> priorityName = this.cachePriority_new(priority, cachePriority);
                Map<String, String> brandPriority = brandPriorityRepository.queryByCondition(locationId, fittingMessage.get("id").toString(), brandId);

                if (!locationAndFittingMessage.add(location.get("id") + brand.get("id").toString() + fittingMessage.get("id").toString())) throw new RuntimeException("导入重复数据，请重新导入！");

                newDataArray.add(0);
                newDataArray.add(brandPriority.size() == 0 ? "" : brandPriority.get("ID"));
                newDataArray.add(location);
                newDataArray.add(location.get("name"));
                newDataArray.add(fittingMessage);
                newDataArray.add(brand);
                newDataArray.add(priorityName);
                newDataArray.add(valid);
                newDataArray.add(brandPriority.size() == 0 ? "" : brandPriority.get("VERSION"));
                newDataArray.add(null);

                dataList.add(MapUtil.mapped(newDataArray));
                distinct.add(locationId + fittingMessageName);
            });
        });

        titleColumnArray.addAll(dataList);
        return key.get().toString();
    }

    // 导入 - 缓存已查过的组合配件
    private Map<String, Object> cacheFittingMessage_new(String fittingMessageName, Map<String, Map<String, Object>> cacheFittingMessage) {
        if (cacheFittingMessage.get(fittingMessageName) == null) {
            FittingMessage fittingMessage = fittingMessageRepository.findOneName(fittingMessageName);
            Optional.ofNullable(fittingMessage).orElseThrow( ()-> new RuntimeException("没有找到对应组合配件的记录，组合配件名称为：" + fittingMessageName) );
            cacheFittingMessage.put(fittingMessageName, MapUtil.mapper("id", fittingMessage.getId(), "name", fittingMessage.getName()));
        }
        return cacheFittingMessage.get(fittingMessageName);
    }

    // 导入 - 缓存已查过的品牌
    private Map<String, Object> cacheBrand_new(String brandId, Map<String, Map<String, Object>> cacheBrand) {
        if (cacheBrand.get(brandId) == null) {
            Brand brand = brandRepository.findOne(brandId);
            Optional.ofNullable(brand).orElseThrow( ()-> new RuntimeException("没有找到对应品牌的记录，品牌编码为：" + brandId) );
            cacheBrand.put(brandId, MapUtil.mapper("id", brand.getId(), "name", brand.getName()));
        }
        return cacheBrand.get(brandId);
    }

    // 导入 - 缓存已查过的仓库
    private Map<String, Object> cacheLocation_new(String locationId, Map<String, Map<String, Object>> cacheLocation) {
        if (cacheLocation.get(locationId) == null) {
            Location location = locationRepository.findOne(locationId);
            Optional.ofNullable(location).orElseThrow( ()-> new RuntimeException("没有找到对应仓库编码的记录，仓库编码为：" + locationId) );
            cacheLocation.put(locationId, MapUtil.mapper("id", location.getId(), "name", location.getName()));
        }
        return cacheLocation.get(locationId);
    }

    // 导入 - 缓存已查过的优先级
    private Map<String, Object> cachePriority_new(String priorityId, Map<String, Map<String, Object>> cachePriority) {
        if (cachePriority.get(priorityId) == null) {
            Enumeration priority = enumerationRepository.findOne(priorityId);
            Optional.ofNullable(priority).orElseThrow( ()-> new RuntimeException("没有找到对应优先级的记录，优先级编码为：" + priorityId) );
            cachePriority.put(priorityId, MapUtil.mapper("id", priority.getId(), "description", priority.getDescription()));
        }
        return cachePriority.get(priorityId);
    }


    /**
     * 手动查找优先级配置
     * @param request
     * @return
     */
    public List<Map<String, Object>> findAllManual(SimpleRequest request){
        JSONObject object = request.getJO();

        if (Objects.isNull(object.get("location")) && Objects.isNull(object.get("brand"))
                && Objects.isNull(object.get("fittingName")) && Objects.isNull(object.get("valid"))) {
            throw new RuntimeException("查询条件不能为空!!!");
        }
        //按条件查询
        JSONArray resultArray = SpringManager.getBean(BrandPriorityDao.class).queryBrandPriority(object);

        //拼装前端展示数据
        List result = resultArray.stream().map(
                item -> {
                    JSONObject jsonObject = (JSONObject) item;
                    return  MapUtil.mapper(
                            "inquirySelectState",false,//多选款默认不勾选
                            "id",jsonObject.getString("ID"),
                            "location",MapUtil.mapper("id",jsonObject.getString("LOCATION_ID"),"name",jsonObject.getString("LOCATION_NAME")),
                            "locationName",jsonObject.getString("LOCATION_NAME"),
                            "fittingName",MapUtil.mapper("id",jsonObject.getString("FITTING_NAME_ID"),"name",jsonObject.getString("FITTING_NAME")),
                            "brand",MapUtil.mapper("id",jsonObject.getString("BRAND_ID"),"name",jsonObject.getString("BRAND_NAME")),
                            "priority",MapUtil.mapper("id",jsonObject.getString("PRIORITY"),"description",jsonObject.getString("PRIORITY_NAME")),
                            "valid",jsonObject.getBoolean("VALID"),
                            "version",jsonObject.getString("VERSION")
                    );
                }
        ).collect(Collectors.toList());
        if (result.size() == 0 ){
            throw new RuntimeException("未找到满足条件得数据!!!");
        }
        return  result;
    }

    /**
     * 放弃编辑回显当前数据
     * @param request
     * @return
     */
    public Map brandPriorityFindOne(SimpleRequest request){
        List<BrandPriority> list = request.getA("brandPriorityItems", BrandPriority.class);
        return MapUtil.mapper("brandPriorityItems",list);
    }
}
